//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using OpenLS.Core;
using OpenLS.Spreadsheet.Internals;

namespace OpenLS.Spreadsheet
{
    ///<summary>
    /// Exposes standard cell formats
    ///</summary>
    public static class StandardFormats
    {
        internal static int? GetFormatId(string code)
        {
            Contract.Ensures(Contract.Result<int?>() == null || Contract.Result<int?>().Value >= 0);
            int result = 0;
            foreach (string s in AllFormatCodes)
            {
                if (s == code)
                    return result;
                result++;
            }
            return null;
        }

        private const string currency1 = "$#,##0_);($#,##0)";
        private const string currency2 = "$#,##0_);[Red]($#,##0)";
        private const string currency3 = "$#,##0.00_);($#,##0.00)";
        private const string currency4 = "$#,##0.00_);[Red]($#,##0.00)";
        private static IEnumerable<string> AllFormatCodes
        {
            get
            {

                yield return "General";
                yield return "0";
                yield return "0.00";
                yield return "#,##0";
                yield return "#,##0.00";
                yield return currency1; //\\5
                yield return currency2;
                yield return currency3;
                yield return currency4; //\\8
                yield return "0%";
                yield return "0.00%"; //10
                yield return "0.00E+00";
                yield return "# ?/?";
                yield return "# ??/??";
                yield return "m/d/yyyy";
                yield return "d-mmm-yy";
                yield return "d-mmm";
                yield return "mmm-yy";
                yield return "h:mm AM/PM";
                yield return "h:mm:ss AM/PM";
                yield return "h:mm"; //20
                yield return "h:mm:ss";
                yield return "m/d/yyyy h:mm";
                yield return "General";
                yield return "General";
                yield return "General";
                yield return "General";
                yield return "m/d/yyyy";
                yield return "m/d/yyyy";
                yield return "m/d/yyyy";
                yield return "m/d/yyyy";//30
                yield return "m/d/yyyy";
                yield return "h:mm:ss";
                yield return "h:mm:ss";
                yield return "h:mm:ss";
                yield return "h:mm:ss";
                yield return "mm/dd/yyyy";
                yield return "#,##0_);(#,##0)";
                yield return "#,##0_);[Red](#,##0)";
                yield return "#,##0.00_);(#,##0.00)";
                yield return "#,##0.00_);[Red](#,##0.00)"; //40
                yield return "_(* #,##0_);_(* (#,##0);_(* \"-\"_);_(@_)";
                yield return "_($* #,##0_);_($* (#,##0);_($* \"-\"_);_(@_)";
                yield return "_(* #,##0.00_);_(* (#,##0.00);_(* \"-\"??_);_(@_)";
                yield return "_($* #,##0.00_);_($* (#,##0.00);_($* \"-\"??_);_(@_)";
                yield return "mm:ss";
                yield return "[h]:mm:ss";
                yield return "mm:ss.0";
                yield return "##0.0E+0";
                yield return "@";
                yield return "m/d/yyyy";
            }
        }
       

        static Format _defaultDateFormat;
        public static Format DefaultDateFormat
        {
            get
            {
                if (_defaultDateFormat == null)
                {
                    _defaultDateFormat = Format.Parse(StringTable.DefaultDateTimeFormat);
                }
                return _defaultDateFormat;
            }
        }
        static readonly object LockObj = new object();
        public static Format GetFormat(int i)
        {
            lock (LockObj)
            {
                build();
                Format result;
                if (_idToFormat.TryGetValue(i, out result))
                    return result;
                if (i != 0)
                    return GetFormat(0);
                throw new InvalidOperationException();
            }
        }

        public static Format BritishPoundCurrencyFormat
        {
            get
            {
                if (_britishPoundCurrencyFormat == null)
                    _britishPoundCurrencyFormat = Format.Parse("[$£]#,##0.00");
                return _britishPoundCurrencyFormat;
            }
        }
        static Format _britishPoundCurrencyFormat;

        public static Format EuroCurrencyFormat
        {
            get
            {
                if (_euroCurrencyFormat == null)
                    _euroCurrencyFormat = Format.Parse("[$€]#,##0.00");
                return _euroCurrencyFormat;
            }
        }
        static Format _euroCurrencyFormat;

        public static Format JapaneseYenCurrencyFormat
        {
            get
            {
                if (_yenCurrencyFormat == null)
                    _yenCurrencyFormat = Format.Parse("[$¥]#,##0.00");
                return _yenCurrencyFormat;
            }
        }
        static Format _yenCurrencyFormat;

        public static Format ChineseCurrencyFormat
        {
            get
            {
                if (_chineseCurrencyFormat == null)
                    _chineseCurrencyFormat = Format.Parse("[$￥#],##0.00");
                return _chineseCurrencyFormat;
            }
        }
        static Format _chineseCurrencyFormat;

        public static Format SwissCurrencyFormat
        {
            get
            {
                if (_swissCurrencyFormat == null)
                    _swissCurrencyFormat = Format.Parse("[$SFr.-100C] #,##0.00");
                return _swissCurrencyFormat;
            }
        }
        static Format _swissCurrencyFormat;

        public static Format ShortDateFormat
        {
            get
            {
                return CodeToFormat[StringTable.DefaultDateTimeFormat];
            }
        }

        static Dictionary<int, Format> _idToFormat;
        static Dictionary<string, Format> CodeToFormat
        {
            get
            {
                build();
                return _codeToFormat;
            }
        }
        static Dictionary<string, Format> _codeToFormat;
        static void build()
        {
            lock (LockObj)
            {
                if (_idToFormat == null)
                {
                    _idToFormat = new Dictionary<int, Format>();
                    _codeToFormat = new Dictionary<string, Format>();
                    int i = 0;
                    foreach (string s in AllFormatCodes)
                    {
                        Format f = Format.Parse(s);
                        _idToFormat[i] = f;
                        _codeToFormat[s] = f;
                        i++;
                    }
                }
            }
        }
    }
}
